#include "uhm.hxx"

#include "uhm/wrapper/fort/util.hxx"

using namespace uhm;

#define UHM_FORT_LINAL_TOKEN 100

static int s_argc;
static char *s_argv[UHM_FORT_LINAL_TOKEN];
static std::string s_tokens[UHM_FORT_LINAL_TOKEN];

F_void UHM_C2F(uhm_initialize)(const F_char *argv) {
  std::stringstream ss;
  ss << argv;
  s_argc = 0;
  while (ss >> s_tokens[s_argc]) {
    UHM_ERROR(s_argc < UHM_FORT_LINAL_TOKEN, ">> Too many input arguments");
    s_argv[s_argc] = (char*)(s_tokens[s_argc].c_str());
    ++s_argc;
  }
  initialize(s_argc, s_argv);
}
F_void UHM_C2F(uhm_finalize)() {
  for (Int_ i=0;i<s_argc;++i) {
    s_argv[i] = NULL;
    s_tokens[i].clear();
  }
  s_argc = 0;

  finalize();
}

F_void UHM_C2F(uhm_hold)() { hold(); }

F_void UHM_C2F(uhm_stopwatch)(F_double *t) { *t = stopwatch(); }

F_void UHM_C2F(uhm_time_begin)(F_int *level) { time_begin(*level); }
F_void UHM_C2F(uhm_time_end)() { time_end(); }
F_void UHM_C2F(uhm_time_stack_size)(F_int *size) { *size = time_stack_size(); }
F_void UHM_C2F(uhm_time_flush)() { time_flush(); }

F_void UHM_C2F(uhm_time_in)() { 
  std::stringstream out;
  out << "[UHM] fortran, time stack  " << time_stack_size();
  time_in(out.str().c_str()); 
}
F_void UHM_C2F(uhm_time_out)(F_double *t) { *t = time_out(); }

F_void UHM_C2F(uhm_storage_counter_reset)() { storage_counter_reset(); }
F_void UHM_C2F(uhm_storage_counter)(F_double *storage, F_double *max_storage) {
  storage_counter(*storage, *max_storage);
}

F_void UHM_C2F(uhm_verbose_begin)() { verbose_begin();}
F_void UHM_C2F(uhm_verbose_end)() { verbose_end();}

F_void UHM_C2F(uhm_get_verbose)(F_int *verbose) { *verbose = get_verbose(); }
F_void UHM_C2F(uhm_get_num_threads)(F_int *nthreads) { *nthreads = get_num_threads(); }

F_void UHM_C2F(uhm_option_begin)() { option_begin(); }
F_void UHM_C2F(uhm_option_end)() { option_end(); }

// fortran is weird, when they pass three char*, they use common space
// ex) "def", "man" -- > "mandef" like this.
F_void UHM_C2F(uhm_get_option_bool)(const F_char *opt, const F_char *text, F_bool *def, F_bool *val) { 
  get_option_bool(opt, text, "fortran", *def, *val);
}

F_void UHM_C2F(uhm_get_option_int)(const F_char *opt, const F_char *text, F_int *def, F_int *val) { 
  get_option_int(opt, text, "fortran", *def, *val);
}
F_void UHM_C2F(uhm_get_option_double)(const F_char *opt, const F_char *text, F_double *def, F_double *val) { 
  get_option_double(opt, text, "fortran", *def, *val);
}

